package com.gopay.bis.cbrmb.server;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Map;

import javax.servlet.ServletContext;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.gopay.common.constants.cbrmb.CbRmbBankConstants;
import com.gopay.common.domain.bank.ccb.cbrmb.req.CbRmbNotificationMsg;
import com.gopay.common.domain.bank.ccb.cbrmb.res.CbRmbResponseMsg;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.cbrmb.BeanMapper;
import com.gopay.common.util.cbrmb.FileUtils;
import com.gopay.remote.bank.cbrmb.CbRmbCcbBankRemoteService;

/**
 * 
 * @ClassName: CbRmbProcessSocketData
 * @Description: 客户端数据处理
 * @author gd.cui
 * @date 2016年7月11日 上午11:45:50 ww.gopay.com.cn Inc.All rights reserved.
 */
public class CbRmbProcessSocketData extends Thread {

	private static final Logger logger = LoggerFactory.getLogger(CbRmbProcessSocketData.class);

	private Socket socket;

	private ServletContext servletContext;

	private Map<String, String> cbrConfig;

	private CbRmbCcbBankRemoteService cbRmbCcbBankRemoteServiceClient;

	@SuppressWarnings("unchecked")
	public void init() {
		ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
		cbRmbCcbBankRemoteServiceClient = (CbRmbCcbBankRemoteService) context
				.getBean("cbRmbCcbBankRemoteServiceClient");
		cbrConfig = (Map<String, String>) context.getBean("cbrConfig");
	}

	public CbRmbProcessSocketData() {
		super();
	}

	public CbRmbProcessSocketData(Socket socket, ServletContext servletContext) {
		this.socket = socket;
		this.servletContext = servletContext;
		init();
	}

	@Override
	public void run() {
		logger.error("******* cbrmb socket server start CbRmbProcessSocketData ");
		InetAddress remoteAddress = socket.getInetAddress();
		String remoteIp = remoteAddress.getHostAddress();
		logger.error("remote ip :" + remoteIp);
		OutputStream os = null;
		InputStream is = null;
		CbRmbNotificationMsg notificationMsg = null;
		CbRmbResponseMsg responseMsg = null;
		try {
			os = socket.getOutputStream();
			is = socket.getInputStream();
			logger.error("*****回盘-接受socket数据流信息");
			//byte[] source = FileUtils.toByteArray(is);
			byte[] source = toByteArray(is);
			logger.error("*****回盘-接受socket数据流信息" + source.length);
			notificationMsg = new CbRmbNotificationMsg(source);
			logger.error("*****回盘-接受到socket信息:" + ReflectionToStringBuilder.toString(notificationMsg));
			responseMsg = checkFile(source, notificationMsg);
			logger.error("*****回盘-返回数据信息:" + ReflectionToStringBuilder.toString(responseMsg));
			os.write(responseMsg.getByteData());
			os.flush();
		} catch (Exception e) {
			logger.error(" *********数据处理异常：", e);
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (is != null) {
				try {
					is.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != socket) {
				logger.info(" *********release connect socket");
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		if (notificationMsg != null && responseMsg != null) {
			String respCode = "";
			try {
				respCode = cbRmbCcbBankRemoteServiceClient.callBIS(notificationMsg, responseMsg);
			} catch (GopayException e) {
				logger.error("回盘信息处理错误：", e);
			}
			logger.info(" *****回盘-call BIS respCode " + respCode);
		}
	}

	/**
	 * 
	 * @Description: 文件校验，并返回信息
	 * @param source
	 * @param notificationMsg
	 * @return
	 * @author gd.cui
	 */
	private CbRmbResponseMsg checkFile(byte[] source, CbRmbNotificationMsg notificationMsg) {
		CbRmbResponseMsg responseMsg = BeanMapper.map(notificationMsg, CbRmbResponseMsg.class);
		if (source != null && source.length >= CbRmbNotificationMsg.MSG_NOTIFICATION_LENGTH) {
			responseMsg.setRetCode(CbRmbBankConstants.SUCCESS);
			responseMsg.setRetMsg("请求接收成功");
		} else {
			responseMsg.setRetCode("900004");
			responseMsg.setRetMsg("HTTP请求错误，报文not enough");
		}
		return responseMsg;
	}

	public Map<String, String> getCbrConfig() {
		return cbrConfig;
	}

	public void setCbrConfig(Map<String, String> cbrConfig) {
		this.cbrConfig = cbrConfig;
	}
	
	
	public byte[] toByteArray(InputStream input) throws Exception {
	       try {
	            ByteArrayOutputStream output = new ByteArrayOutputStream();
	            byte[] buffer = new byte[4096];
	            int n = input.read(buffer);
	            output.write(buffer, 0, n);
	            logger.error("=====back==" + new String(output.toByteArray(), "GBK"));
	            return output.toByteArray();
	        } catch (Exception e) {
	        	 throw new Exception(e.getMessage());
	        }
	    }

}
